#pragma once
#include <iostream>
#include <sys/epoll.h>
#include "InetAddr.hpp"
#include "Connection.hpp"
class Channel : public Connection
{
public:
    Channel(int sockfd, Inet_Addr& client)
    :_sockfd(sockfd),//将套接字文件符号保存到管理对象中
     _client(client)//保存客户端信息
    {
        SetNonBlock(_sockfd);//将文件描述符设置为非阻塞
    }

    int GetSockFd() override
    {
        return _sockfd;
    }
    void Recver() override
    {
        char buffer[1024];
        while(true)
        {
            buffer[0] = 0;//清空数组
            ssize_t n = recv(_sockfd, buffer, sizeof buffer - 1, 0);//0是阻塞读取,但如果 fd 已经是非阻塞，写 0 也行
            if(n > 0)
            {
                buffer[n] = 0;
                _inbuffer += buffer;
            }
            else if(n == 0)
            {
                
                Excepter();//对端关闭连接异常处理
                break;
            }
            else
            {
                if(errno == EAGAIN || errno == EWOULDBLOCK)
                {
                    break;//无数据可读
                }
                else if(errno == EINTR)
                {
                    continue;//读取时被打断
                }
                else
                {
                    Excepter();//读取出错
                    return;
                }
            }
        }
        //处理数据的逻辑一定要在外面做
        if(!_inbuffer.empty())
        {
            _outbuffer += _handler(_inbuffer);
        }
        if(!_outbuffer.empty())
        {
            Sender();
        }
    }
    void Sender() override
    {
        while(true)
        {
            ssize_t n = send(_sockfd, _outbuffer.c_str(), _outbuffer.size(), 0);//发送数据
            if(n > 0)
            {
                //发送成功清空缓冲区
                _outbuffer.erase(0, n);
                if(_outbuffer.empty())
                {
                    break;
                }
            }
            else if(n == 0)
            {
                //不代表对端关闭,只是读了0个数据
                break;
            }
            else
            {
                if(errno == EAGAIN || errno == EWOULDBLOCK)
                {
                    //无数据可读
                    break;
                }
                else if(errno == EINTR)
                {
                    continue;//读取时被打断
                }
                else 
                {
                    Excepter();//读取出错
                    return;
                }
            }
        }

        //数据发送完毕或者发送条件不具备

        if(!_outbuffer.empty())
        {
            //发送条件不具备(开启对写事件的关心),内核缓冲区被写满了,写事件默认就是就绪的
            GetOwner()->EnableReadWrite(_sockfd, true, true);
        }
        else
        {
            GetOwner()->EnableReadWrite(_sockfd, true, false);
        }
    }

    void Excepter() override
    {
        GetOwner()->DelConnection(_sockfd);//文件描述符出错关闭
    }
    ~Channel()
    {
        
    }
private:
    int _sockfd;
    std::string _inbuffer;//发送缓冲区
    std::string _outbuffer;//接收缓冲区
    Inet_Addr _client;
};